﻿#region Imports
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using CommonUtilities.Attributes;
using CommonUtilities.Commands;
using CommonUtilities.Enums;
using CommonUtilities.Extensions;
using CommonUtilities.Models;
using CommonUtilities.Util;
#endregion Imports

namespace DirectoryAnalyzer.Controls.ViewModels
{
    public class FileAnalyzerViewModel : BaseViewModel
    {
        #region Declarations
        public ICommand ExtnSelectionChangeCommand { get; private set; }
        public ICommand LoadFilesCommand { get; private set; }
        #endregion Declarations

        #region Properties
        private string basePath;
        public string BasePath
        {
            get { return basePath; }
            set
            {
                basePath = value; RaisePropertyChanged("BasePath");

                CanLoadFiles = BasePath.ValidatePath(ePathValidation.Directory);
                ValidationColour = CanLoadFiles ? Brushes.Green : Brushes.Red;
                if (CanLoadFiles & AutoLoad) LoadFilesCommand.Execute(null);
            }
        }

        private ObservableCollection<string> allPaths = new ObservableCollection<string>();
        public ObservableCollection<string> AllPaths
        {
            get { return allPaths; }
            set
            {
                allPaths = value;
                RaisePropertyChanged("AllPaths");

                LoadHierarchical();
            }
        }

        private ObservableCollection<ExtnHierarchy> allHierarchicalData;
        public ObservableCollection<ExtnHierarchy> AllHierarchicalData
        {
            get { return allHierarchicalData; }
            set { allHierarchicalData = value; RaisePropertyChanged("AllHierarchicalData"); }
        }

        private ObservableCollection<ExtnHierarchy> allHierarchicalData_Filtered;
        public ObservableCollection<ExtnHierarchy> AllHierarchicalData_Filtered
        {
            get { return allHierarchicalData_Filtered; }
            set { allHierarchicalData_Filtered = value; RaisePropertyChanged("AllHierarchicalData_Filtered"); }
        }

        private Brush validationColour;
        public Brush ValidationColour
        {
            get { return validationColour; }
            set { validationColour = value; RaisePropertyChanged("ValidationColour"); }
        }

        private bool canLoadFiles;
        public bool CanLoadFiles
        {
            get { return canLoadFiles; }
            set { canLoadFiles = value; RaisePropertyChanged("CanLoadFiles"); }
        }

        private bool autoLoad;
        public bool AutoLoad
        {
            get { return autoLoad; }
            set
            {
                autoLoad = value;
                RaisePropertyChanged("AutoLoad");

                if (autoLoad & CanLoadFiles) LoadFilesCommand.Execute(null);
            }
        }

        private Dictionary<string, string> allFilters;
        public Dictionary<string, string> AllFilters
        {
            get { return allFilters; }
            set { allFilters = value; RaisePropertyChanged("AllFilters"); }
        }

        private bool isAscending;
        public bool IsAscending
        {
            get { return isAscending; }
            set
            {
                isAscending = value;
                RaisePropertyChanged("IsAscending");

                SortExtensions();
            }
        }

        private string selectedFilter;
        public string SelectedFilter
        {
            get { return selectedFilter; }
            set
            {
                selectedFilter = value;
                RaisePropertyChanged("SelectedFilter");

                bool supressSort;
                supressSort = true;
                IsAscending = (selectedFilter == "ExtnName");
                supressSort = false;
                SortExtensions();
            }
        }
        #endregion Properties

        #region Constructors
        public FileAnalyzerViewModel()
        {
            ExtnSelectionChangeCommand = new RelayCommand<ExtnHierarchy>((parameter) => { FilterExtnDetails(); });
            LoadFilesCommand = new RelayCommand<string>((parameter) => { LoadFiles(); });

            IsAscending = true;
            AllFilters = AttributeLists<ExtnHierarchy>.PropertyMapSortable;
            SelectedFilter = "ExtnName";

            AutoLoad = true;
            BasePath = "Autogenerate dgv cols: e.Column = new DataGridTemplateColumn.....";

            // RKD debug
            Clipboard.SetText(@"J:\[TV series]");
        }
        #endregion Constructors

        #region Events

        #endregion Events

        #region Methods
        private void LoadFiles()
        {
            AllPaths = Directory.GetFiles(BasePath, "*.*", SearchOption.AllDirectories).ToObservableCollection();
        }

        private void LoadHierarchical()
        {
            AllHierarchicalData = AllPaths._Select(path => Path.GetExtension(path).RemoveExtnChars())
                .Distinct()._OrderBy()._Select(extn =>
                {
                    ObservableCollection<string> filePaths
                        = AllPaths._Where(path => Path.GetExtension(path).RemoveExtnChars() == extn).ToObservableCollection();

                    double totSize = 0;
                    filePaths._ForEach(path => totSize += new FileInfo(path).GetLength());

                    ExtnHierarchy tmp = new ExtnHierarchy
                         {
                             ExtnName = extn.RemoveExtnChars().ToUpper(),
                             IsSelected = true,
                             IsExpanded = false,
                             TotByteSize = totSize,
                             TotSize = new MemoryMgmt(eByteValueType.B, totSize).PracticalSize,
                             AllFiles = filePaths
                         };

                    return tmp;
                }).ToObservableCollection();

            FilterExtnDetails();
        }

        private void FilterExtnDetails()
        {
            AllHierarchicalData_Filtered = AllHierarchicalData._Where(extn => extn.IsSelected)
                ._OrderBy(extn => extn.ExtnName).ToObservableCollection();
        }

        private void SortExtensions()
        {
            AllHierarchicalData = AllHierarchicalData.OrderByProperty(selectedFilter, IsAscending)
                .ThenByDirection(extn => extn.ExtnName, IsAscending).ToObservableCollection();
        }
        #endregion Methods
    }

    public class ExtnHierarchy : NotifyPropertyChanged
    {
        #region Properties
        public bool IsExpanded { get; set; }

        [DisplayName("Extension")]
        [Sortable]
        public string ExtnName { get; set; }

        [DisplayName("Tot. byte size")]
        [Sortable]
        public double TotByteSize { get; set; }

        public string TotSize { get; set; }

        public ObservableCollection<string> AllFiles { get; set; }

        private bool isSelected;
        [DisplayName("Selected?")]
        [Sortable]
        public bool IsSelected
        {
            get { return isSelected; }
            set { isSelected = value; RaisePropertyChanged("IsSelected"); }
        }
        #endregion Properties

        public ExtnHierarchy()
        {
            AllFiles = new ObservableCollection<string>();
        }
    }
}
